Skip to content

Traffic-Based App Rewards: Integrate the Reward Computation Trigger with the necessary daml contracts#5119

Open
adetokunbo wants to merge 19 commits into
dfordivam/cip-104-sv-app-rewards-feature-branchfrom
adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger
Open

Traffic-Based App Rewards: Integrate the Reward Computation Trigger with the necessary daml contracts#5119
adetokunbo wants to merge 19 commits into
dfordivam/cip-104-sv-app-rewards-feature-branchfrom
adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger

Conversation

@adetokunbo
Copy link
Copy Markdown
Contributor

@adetokunbo adetokunbo commented Apr 20, 2026

Fixes #4383
Fixes #4570

This integrates the RewardComputationTrigger with the Daml contracts from which it obtains the values it uses in its calculations

Pull Request Checklist

Cluster Testing

  • If a cluster test is required, comment /cluster_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.
  • If a hard-migration test is required (from the latest release), comment /hdm_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.
  • If a logical synchronizer upgrade test is required (from canton-3.5), comment /lsu_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.

PR Guidelines

  • Include any change that might be observable by our partners or affect their deployment in the release notes.
  • Specify fixed issues with Fixes #n, and mention issues worked on using #n
  • Include a screenshot for frontend-related PRs - see README or use your favorite screenshot tool

Merge Guidelines

  • Make the git commit message look sensible when squash-merging on GitHub (most likely: just copy your PR description).

@adetokunbo adetokunbo added this to the Traffic-Based App Rewards milestone Apr 20, 2026
@adetokunbo adetokunbo self-assigned this Apr 20, 2026
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-add-lookup-open-mining-round-by-number branch from 2da39fa to 9a37516 Compare April 20, 2026 08:59
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch from 93367ef to fd731a7 Compare April 20, 2026 09:02
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch from f1fc9f1 to eb9c129 Compare April 21, 2026 02:14
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch 2 times, most recently from 5b32f44 to 68c9cb7 Compare April 23, 2026 21:12
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-add-lookup-open-mining-round-by-number branch from 9a37516 to 0a01ed4 Compare May 7, 2026 06:40
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch from 6074b07 to e13324c Compare May 7, 2026 06:57
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-add-lookup-open-mining-round-by-number branch from 0a01ed4 to 22f4aad Compare May 7, 2026 07:34
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch from e13324c to b66e52e Compare May 7, 2026 07:35
Base automatically changed from adetokunbo/cip-104-add-lookup-open-mining-round-by-number to dfordivam/cip-104-sv-app-rewards-feature-branch May 8, 2026 09:57
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch 2 times, most recently from 6981b33 to eba9097 Compare May 12, 2026 08:08
@adetokunbo
Copy link
Copy Markdown
Contributor Author

@rautenrieth-da, this is the PR that integrates the RewardComputationTrigger into this feature branch. PTAL

Copy link
Copy Markdown
Contributor

@rautenrieth-da rautenrieth-da left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trigger tries to run the reward computation for each round, starting from the earliest round with the rewardConfig set. This results in a gapless history of reward data, but can potentially lead to a lot of lag and useless computation when a SV node is catching up.

We can change the whole logic for what round to process to a simple "Fetch the oldest active CalculateRewardsV2 contract, and calculate the root hash its round".

Why does this work?

  • We do not need a gapless history for the reward data. We only need it for processing rewards. Once all rewards are processed, the data will still be persisted in the UpdateHistory of CalculateRewardsV2 and ProcessRewardsV2 contracts. We therefore don't expect to ever need to make the internal scan API for reward processing public.
  • The reward processing trigger may read data from other scan instances if its own scan instance doesn't have the data, so we don't need to implement any backfilling:
    • When turning a CalculateRewardsV2 into a ProcessRewardsV2, we need to make sure the voting on the root hash is BFT safe. If the round is after the completeness boundary of an SV, the SV should use its own scan data. If the round is before (e.g., because the SV has just onboarded or bumped their store version), the SV will do a BFT read from other SVs to avoid deadlocking the consensus.
    • When breaking down ProcessRewardsV2 contracts, each SV may read reward data from any single other scan instead of its own. There is no BFT read required - since we have already voted on the root hash, the ProcessRewardsV2_ProcessBatch choice would immediately fail if called with malicious data. We would only have a problem if ALL nodes that computed the root hash went offline before the processing of rewards is finished.

This is all very complex, let's discuss this in our next call.

@dfordivam dfordivam force-pushed the dfordivam/cip-104-sv-app-rewards-feature-branch branch from 79358d5 to c39e5af Compare May 19, 2026 09:01
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
…undByNumber

Signed-off-by: Tim Emiola <adetokunbo@emio.la>
adetokunbo and others added 6 commits May 19, 2026 23:26
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Divam <dfordivam@gmail.com>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
…active

Signed-off-by: Tim Emiola <adetokunbo@emio.la>
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch from eba9097 to b8e15a0 Compare May 20, 2026 00:44
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
@adetokunbo adetokunbo force-pushed the adetokunbo/cip-104-sv-app-rewards-integrate-reward-computation-trigger branch from b8e15a0 to ff8020c Compare May 20, 2026 00:48
@adetokunbo adetokunbo changed the base branch from dfordivam/cip-104-sv-app-rewards-feature-branch to release-line-0.6.4 May 20, 2026 01:01
@adetokunbo adetokunbo changed the base branch from release-line-0.6.4 to dfordivam/cip-104-activity-record-computation-base May 20, 2026 01:01
@adetokunbo adetokunbo changed the base branch from dfordivam/cip-104-activity-record-computation-base to dfordivam/cip-104-activity-record-computation May 20, 2026 01:02
@adetokunbo adetokunbo changed the base branch from dfordivam/cip-104-activity-record-computation to dfordivam/cip-104-activity-record-computation-base May 20, 2026 01:02
@adetokunbo adetokunbo changed the base branch from dfordivam/cip-104-activity-record-computation-base to dfordivam/cip-104-sv-app-rewards-feature-branch May 20, 2026 01:03
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
@adetokunbo
Copy link
Copy Markdown
Contributor Author

This trigger tries to run the reward computation for each round, starting from the earliest round with the rewardConfig set. This results in a gapless history of reward data, but can potentially lead to a lot of lag and useless computation when a SV node is catching up.

We can change the whole logic for what round to process to a simple "Fetch the oldest active CalculateRewardsV2 contract, and calculate the root hash its round".

....

This is all very complex, let's discuss this in our next call.

@dfordivam , @rautenrieth-da this the trigger is now simplified as discussed, PTAL

// For each eligible round until the configured parallelism limit, look
// up OpenMiningRound and extract inputs. The trigger will handle the
// remainder in subsequent polls.
tasks <- Future.traverse(eligible.take(context.config.parallelism)) { roundNumber =>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did we add parallelism here. This seems to be fairly simple DB lookup for task creation.
Also I think MonadUtil.parTraverseWithLimit is the correct API to use

Copy link
Copy Markdown
Contributor Author

@adetokunbo adetokunbo May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC parTraverseWithLimit will compute everything in parallel? We really only want the first n of the parallelism limit. I've actually pushed another commit with a fix that adds a helper to address this PTAL

As to why we add parallelism here, this emulating how the parallelism config is used in ExpiresRewardsCouponsTrigger, with a similar idea: to avoid contention in any scenario where there are large number of potential tasks.

.map(_.exists(_ >= task.roundNumber))
rewardsReferenceStore.multiDomainAcsStore
.lookupContractById(CalculateRewardsV2.COMPANION)(task.calculateRewardsId)
.map(_.isEmpty)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing check for already computed totals for this round

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that check happens when the tasks are filtered (as it does), does it also need to happen here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would be called only when completeTask fails, before doing the retry. If completeTask fails ever happened after total were actually calculated, then completeTask would be called again and it would fail again, resulting in a loop. This is my understanding, but I will let @rautenrieth-da to also provide clarifications on this.

Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Signed-off-by: Tim Emiola <adetokunbo@emio.la>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants